"""文件夹工具模块
处理用户脚本文件夹的文件系统存储
"""
import os
import logging
import json
import traceback
from pathlib import Path
from .file_utils import get_user_script_directory
from services.shared.log_utils import log_error, log_info, log_system_event

# 获取日志记录器
logger = logging.getLogger(__name__)

def create_script_folder(username, folder_name, parent_folder_path=None):
    """
    在文件系统中创建脚本文件夹
    
    Args:
        username (str): 用户名
        folder_name (str): 文件夹名称
        parent_folder_path (str, optional): 父文件夹路径，如果为None则创建在用户根目录下
        
    Returns:
        str: 创建的文件夹路径
    """
    try:
        if parent_folder_path:
            # 如果有父文件夹，则在父文件夹下创建
            folder_path = os.path.join(parent_folder_path, folder_name)
        else:
            # 否则在用户脚本根目录下创建
            user_dir = get_user_script_directory(username)
            folder_path = os.path.join(user_dir, folder_name)
        
        os.makedirs(folder_path, exist_ok=True)
        logger.info(f"已在文件系统中创建用户 {username} 的脚本文件夹: {folder_path}")
        return folder_path
    except Exception as e:
        logger.error(f"在文件系统中创建用户 {username} 的脚本文件夹 {folder_name} 失败: {str(e)}")
        
        # 记录详细的系统错误日志
        log_error(
            "folder_utils_create_script_folder_failed",
            {
                "username": username,
                "folder_name": folder_name,
                "parent_folder_path": parent_folder_path,
                "folder_path": locals().get('folder_path', 'unknown'),
                "error_type": type(e).__name__,
                "error_message": str(e),
                "stack_trace": traceback.format_exc(),
                "execution_context": {
                    "function": "create_script_folder",
                    "module": "shared.folder_utils",
                    "operation": "folder_creation"
                }
            }
        )
        raise

def get_folder_path(username, folder_name, parent_folder_path=None):
    """
    获取脚本文件夹路径
    
    Args:
        username (str): 用户名
        folder_name (str): 文件夹名称
        parent_folder_path (str, optional): 父文件夹路径，如果为None则表示在用户根目录下
        
    Returns:
        str: 文件夹路径
    """
    if parent_folder_path:
        return os.path.join(parent_folder_path, folder_name)
    else:
        user_dir = get_user_script_directory(username)
        return os.path.join(user_dir, folder_name)

def get_folder_full_path(folder, user_id, username, db_session=None, return_both=False):
    """
    递归获取文件夹的完整路径
    
    Args:
        folder: 文件夹对象，必须包含id、parent_id和name属性
        user_id: 用户ID
        username: 用户名
        db_session: 数据库会话对象，如果为None则使用当前会话
        return_both: 是否同时返回相对路径和绝对路径
        
    Returns:
        如果return_both为True，返回(relative_path, full_path)元组
        否则返回relative_path
    """
    try:
        # 导入放在函数内部避免循环导入
        from services.shared.models.script import ScriptFolder
        
        # 使用递归方式构建完整路径
        def build_path(current_folder):
            logger.info(f"构建路径 - 当前文件夹: ID={current_folder.id}, 名称={current_folder.name}, 父ID={current_folder.parent_id}")
            if current_folder.parent_id is None:
                # 如果是根文件夹，直接返回名称
                logger.info(f"根文件夹，返回: [{current_folder.name}]")
                return [current_folder.name]
            else:
                # 查找父文件夹
                try:
                    if db_session:
                        parent = db_session.query(ScriptFolder).filter_by(id=current_folder.parent_id, user_id=user_id).first()
                    else:
                        # 确保在应用上下文中执行查询
                        from flask import current_app
                        with current_app.app_context():
                            parent = ScriptFolder.query.filter_by(id=current_folder.parent_id, user_id=user_id).first()
                    
                    if parent is None:
                        logger.warning(f"找不到文件夹ID {current_folder.parent_id} 的父文件夹，将使用用户根目录")
                        return [current_folder.name]
                    
                    logger.info(f"找到父文件夹: ID={parent.id}, 名称={parent.name}")
                    # 递归获取父文件夹路径，然后添加当前文件夹名称
                    parent_path = build_path(parent)
                    result = parent_path + [current_folder.name]
                    logger.info(f"构建完成，路径: {result}")
                    return result
                except Exception as e:
                    logger.error(f"查询父文件夹时出错: {e}")
                    logger.warning(f"无法查询父文件夹，将使用当前文件夹作为根目录")
                    return [current_folder.name]
        
        # 构建从根到当前文件夹的路径列表
        folder_path_parts = build_path(folder)
        
        # 构建完整路径
        user_dir = get_user_script_directory(username)
        full_path = os.path.join(user_dir, *folder_path_parts)
        
        # 确保路径存在 - 创建完整路径而不仅仅是父目录
        os.makedirs(full_path, exist_ok=True)
        logger.info(f"确保文件夹路径存在: {full_path}")
        logger.info(f"文件夹路径组成部分: {folder_path_parts}")
        
        # 计算相对于用户目录的路径
        relative_path = os.path.join(*folder_path_parts)
        logger.info(f"相对路径: {relative_path}")
        logger.info(f"绝对路径: {full_path}")
        
        # 根据参数返回相对路径或者同时返回相对路径和绝对路径
        if return_both:
            return relative_path, full_path
        else:
            return relative_path
    except Exception as e:
        logger.error(f"获取文件夹 {folder.name} (ID: {folder.id}) 的完整路径失败: {str(e)}")
        
        # 记录详细的系统错误日志
        log_error(
            "folder_utils_get_folder_full_path_failed",
            {
                "folder_name": getattr(folder, 'name', 'unknown'),
                "folder_id": getattr(folder, 'id', 'unknown'),
                "user_id": user_id,
                "username": username,
                "return_both": return_both,
                "error_type": type(e).__name__,
                "error_message": str(e),
                "stack_trace": traceback.format_exc(),
                "execution_context": {
                    "function": "get_folder_full_path",
                    "module": "shared.folder_utils",
                    "operation": "folder_path_resolution"
                }
            }
        )
        
        # 出错时返回用户根目录下的文件夹
        user_dir = get_user_script_directory(username)
        if return_both:
            return folder.name, os.path.join(user_dir, folder.name)
        else:
            return folder.name

def delete_script_folder(folder_path):
    """
    删除脚本文件夹
    
    Args:
        folder_path (str): 文件夹路径
    """
    try:
        if os.path.exists(folder_path) and os.path.isdir(folder_path):
            # 检查文件夹是否为空
            if not os.listdir(folder_path):
                os.rmdir(folder_path)
                logger.info(f"已删除脚本文件夹: {folder_path}")
                
                # 记录成功删除的系统事件
                log_system_event(
                    "INFO",
                    "folder_utils",
                    "脚本文件夹删除成功",
                    {
                        "folder_path": folder_path,
                        "operation": "folder_deletion"
                    }
                )
            else:
                logger.warning(f"脚本文件夹不为空，无法删除: {folder_path}")
                
                # 记录文件夹非空的警告事件
                log_system_event(
                    "WARNING",
                    "folder_utils",
                    "文件夹不为空，无法删除",
                    {
                        "folder_path": folder_path,
                        "operation": "folder_deletion_attempt"
                    }
                )
        else:
            logger.warning(f"脚本文件夹不存在: {folder_path}")
            
            # 记录文件夹不存在的警告事件
            log_system_event(
                "WARNING",
                "folder_utils",
                "文件夹不存在，无法删除",
                {
                    "folder_path": folder_path,
                    "operation": "folder_deletion_attempt"
                }
            )
    except Exception as e:
        logger.error(f"删除脚本文件夹失败: {str(e)}")
        
        # 记录详细的系统错误日志
        log_error(
            "folder_utils_delete_script_folder_failed",
            {
                "folder_path": folder_path,
                "error_type": type(e).__name__,
                "error_message": str(e),
                "stack_trace": traceback.format_exc(),
                "execution_context": {
                    "function": "delete_script_folder",
                    "module": "shared.folder_utils",
                    "operation": "folder_deletion"
                }
            }
        )
        raise